package ca.abubakrsagar.breadboardsim;

import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;

/**
 * This class deals with the panel that will hold the breadboard. It extends
 * JLayeredPane class.
 * 
 * @author Sagar Desai, Mohammad Abubakr
 * @since May 29, 2012
 */

public class BreadboardPanel extends JLayeredPane {

	private Breadboard breadboard = new Breadboard(); // The breadboard object.
	private DragController drgController = new DragController(this); // The controller
																// which will
																// manage the
																// dragging of
																// components.
	private PropertiesPanel propertiesPanel; // The properties panel to display the
										// properties of components.

	private WireController wireController = new WireController(this); // The controller
																// which will
																// allow for the
																// creation of
																// wires on the
																// breadboard.

	private MainSwitch mainSwitch = new MainSwitch(breadboard); // The mainSwitch used
														// to turn the power on
														// or off.
	private MainSwitchController mainSwitchController = new MainSwitchController(
			mainSwitch); // The main switch controller.
	private JLabel mainSwitchLabel = new JLabel("Power Switch"); // Label to display
															// user information
															// for the
															// mainSwitch.
	private JLabel toolboxLabel = new JLabel("Tool Box:"); // The label for the tool box
													// area.

	/**
	 * Creates a new breadboard panel linked to a given PropertiesPanel object.
	 * 
	 * @param proprtiesPanel
	 *            A PropertiesPanel object linked to the Breadboard panel.
	 */
	public BreadboardPanel() {

		// Setup dimensions and layouts for required objects.
		setPreferredSize(new Dimension((900 - 900 / 5), 506));
		setLayout(null);
		setVisible(true);
		setBorder(BorderFactory.createTitledBorder("Breadboard"));
		mainSwitchLabel.setPreferredSize(new Dimension(200, 20));
		toolboxLabel.setPreferredSize(new Dimension(200, 20));
		mainSwitch.addMouseListener(mainSwitchController);
		// Associate the given properties panel with a local variable.
		// Initialize a BreadBoardPanelController using the given
		// propertiesPanel.

		// The controller for the
		// breadboard.

		// Add all required objects to the BreadboardPanel.
		this.add(toolboxLabel);
		this.add(breadboard);
		this.add(mainSwitch);
		this.add(mainSwitchLabel);

		// Add a mouse listener to the panel.

		this.addMouseListener(wireController);

		// Position all objects as needed.
		toolboxLabel.setBounds(50, 420, 200, 20);
		mainSwitchLabel.setBounds(155, 25, 200, 20);
		mainSwitch.setBounds(200, 50, 52, 22);
		breadboard.setBounds(30, 100, 660, 400);
	}

	/**
	 * Calls the drawToolBox method to update locations of the components.
	 */
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		drawToolBox();
	}

	/**
	 * Draws the components in the toolbox in the following order: LED, Resistor
	 * and Switch The components are spaced out according to their sizes and
	 * through the use of a counter.
	 */
	private void drawToolBox() {
		int q = 0; // An instanced counter used for spacing of the components in
					// the toolbox.

		// Set the bounds for all the components which are still in the toolbox
		// (have yet to be dragged).
		for (int i = 0; i < breadboard.getLED().size(); i++) {
			if (breadboard.getLED().get(i).isInToolBox()) {
				breadboard.getLED().get(i)
						.setBounds((q++ * 24) + 100, 450, 25, 21);
			}
		}
		for (int i = 0; i < breadboard.getResistor().size(); i++) {
			if (breadboard.getResistor().get(i).isInToolBox()) {
				breadboard.getResistor().get(i)
						.setBounds((q++ * 30) + 100, 450, 27, 37);
			}
		}
		for (int i = 0; i < breadboard.getSwitch().size(); i++) {
			if (breadboard.getSwitch().get(i).isInToolBox()) {
				breadboard.getSwitch().get(i)
						.setBounds((q++ * 30) + 100, 450, 27, 27);
			}
		}
	}

	/**
	 * After adding mouse and mouse motion listeners to the given LED, that LED
	 * is added to the array list in the breadboard class. The panel is then
	 * repainted to update the view.
	 * 
	 * @param tempLED
	 *            A temporary LED.
	 */
	public void addLED(LED tempLED) {
		tempLED.addMouseListener(drgController);
		tempLED.addMouseMotionListener(drgController);
		tempLED.addMouseListener(propertiesPanel.getBreadboardPanelController());
		breadboard.getLED().add(tempLED);
		add(tempLED);
		repaint();
	}

	/**
	 * After adding mouse and mouse motion listeners to the given Resistor, that
	 * Resistor is added to the array list in the breadboard class. The panel is
	 * then repainted to update the view.
	 * 
	 * @param tempResistor
	 *            A temporary resistor.
	 */
	public void addResistor(Resistor tempResistor) {
		tempResistor.addMouseListener(drgController);
		tempResistor.addMouseMotionListener(drgController);
		tempResistor.addMouseListener(propertiesPanel
				.getBreadboardPanelController());
		breadboard.getResistor().add(tempResistor);
		add(tempResistor);
		repaint();
	}

	/**
	 * After adding mouse and mouse motion listeners to the given resistor, that
	 * resistor is added to the array list in the breadboard class. The panel is
	 * then repainted to update the view.
	 * 
	 * @param tempSwitch
	 *            A temporary switch.
	 */
	public void addSwitch(Switch tempSwitch) {
		tempSwitch.addMouseListener(drgController);
		tempSwitch.addMouseMotionListener(drgController);
		tempSwitch.addMouseListener(propertiesPanel
				.getBreadboardPanelController());
		breadboard.getSwitch().add(tempSwitch);
		add(tempSwitch);
		repaint();
	}

	/**
	 * Creates a new temporary wire which is then added to the ArrayList in the
	 * breadboard class and onto the breadboard panel. The panel is then
	 * repainted to update the view.
	 * 
	 * @param x
	 *            The x value of the first point.
	 * @param y
	 *            The y value of the first point.
	 * @param x1
	 *            The x value of the second point.
	 * @param y1
	 *            The y value of the second point.
	 */
	public void addWire(int x, int y, int x1, int y1) {
		Wire tempWire = new Wire(x, y, x1, y1);
		tempWire.addMouseListener(propertiesPanel
				.getBreadboardPanelController());
		breadboard.getWire().add(tempWire);
		add(tempWire);
		repaint();
	}

	/**
	 * @return The breadboard object.
	 */

	public Breadboard getBreadboard() {
		return breadboard;
	}

	/**
	 * Associates the local properties panel with the specified properties
	 * panel.
	 * 
	 * @param propertiesPanel
	 *            The properties panel.
	 */
	public void setPropertiesPanel(PropertiesPanel propertiesPanel) {
		this.propertiesPanel = propertiesPanel;

	}

	/**
	 * Updates the breadboard panel including location of components and their
	 * states.
	 */
	public void update() {
		for (int i = 0; i < breadboard.getLED().size(); i++) {
			System.out.println("ok");
			add(breadboard.getLED().get(i));
			int x = (breadboard.getLED().get(i).getPosition()[0][0] + 32) * 100;
			int y = 100;
			breadboard.getLED().get(i).setBounds(x, y, 24, 20);
		}
		repaint();
	}

}
